package wsi.exp.exp5;

import java.util.LinkedList;
import java.util.List;

import org.rygh.core.model.common.Pair;
import org.rygh.core.xml.XmlLeaf;
import org.rygh.core.xml.XmlObject;
import org.rygh.semantic.model.rdf.Entity;

public class JudgeGroup {

	class JudgePair extends Pair<String, String> {

		public JudgePair(String left, String right) {
			super(left, right);
		}

		public boolean hasMatch(XmlLeaf node) {
			assert !node.isLeaf();

			if (!node.isLeaf())
				for (XmlLeaf l : node.getChildren()) {
					XmlObject obj = l.getValue();

					String xpath_str = obj.getAttribute("t:xpath");
					String ppath_str = obj.getAttribute("t:predicates");

					if (equalsTo(xpath_str, ppath_str))
						return true;
				}

			if (JudgeTuple.__DEBUG)
				System.out.printf("[info] no match %s\n", this);

			return false;
		}
	}

	private final List<JudgePair> pairs = new LinkedList<>();
	private final boolean defaultValue;

	private String suffix = null;

	public JudgeGroup(boolean defaultValue, String suffix) {
		this.defaultValue = defaultValue;
		this.suffix = suffix;

		if (!defaultValue)
			if (suffix == null || suffix.isEmpty())
				throw new RuntimeException();

	}

	public void add(String xpath, String ppath) {
		pairs.add(new JudgePair(xpath, ppath));
	}

	private Boolean checkSuffix(XmlLeaf node) {
		Entity entity = new Entity(node.getValue().getAttribute("t:url"), false);
		String suf = entity.getSuffix();

		if (defaultValue) {
			if (suffix == null || suffix.isEmpty()) {
				if (!entity.hasSuffix())
					return defaultValue;
			} else {
				if (entity.hasSuffix() && suf.contains(suffix))
					return defaultValue;
			}
		} else {
			if (suffix == null || suffix.isEmpty()) {
				throw new RuntimeException();
			} else {
				if (entity.hasSuffix() && suf.contains(suffix))
					return defaultValue;
			}
		}

		return null;
	}

	/**
	 * a judge group can only judge to its default value (no opposite of default
	 * value). for cannot-judge cases, return null.
	 * 
	 * @param node
	 * @return
	 */
	public Boolean judge(XmlLeaf node) {
		if (defaultValue && pairs.isEmpty())
			return null;

		for (JudgePair p : pairs)
			if (!p.hasMatch(node)) {
				// we require all pairs are matched, if any
				return null;
			}

		return checkSuffix(node);
	}

	@Override
	public String toString() {
		return String.format("[JudgeGroup] default %b, suffix %s, %s",
				defaultValue, suffix, pairs);
	}
}
